<!--
 * @Author: wuheng wuheng@szhbzc.com
 * @Date: 2024-12-16 14:28:23
 * @LastEditors: wuheng wuheng@szhbzc.com
 * @LastEditTime: 2025-03-03 14:28:39
 * @FilePath: \web-appc:\Users\wuheng\Desktop\WugangNew\src\views\dishmana\dishbom\index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <div class="dishaccounting">
    <searchCard @onSearch="searchFn" @onReset="resetFn">
      <el-form :model="dishbomForm" label-width="auto" inline @keyup.enter="searchFn">
        <el-form-item label="菜品编码：">
          <pb-input v-model="dishbomForm.dishCode" placeholder="请输入菜品编码"></pb-input>
        </el-form-item>
        <el-form-item label="菜品名称：">
          <pb-input v-model="dishbomForm.dishName" placeholder="请输入菜品名称"></pb-input>
        </el-form-item>
        <el-form-item label="定价方式：">
          <pb-check :list="priList" @change="SetpricingFn($event)"></pb-check>
        </el-form-item>
        <el-form-item label="成本状态：">
          <pb-check :list="statusList" @change="SetcostStatusFn($event)"></pb-check>
        </el-form-item>
        <el-form-item label="匹配状态：">
          <pb-check :list="matchList" @change="SetskuStatusFn($event)"></pb-check>
        </el-form-item>
        <el-form-item label="供餐模式：">
          <pb-check :list="scopepriList" @change="SetscopepricingFn($event)"></pb-check>
        </el-form-item>
      </el-form>
    </searchCard>
    <div class="flex-1">
      <pb-card padding="0" height="100%">
        <div class="content-box">
          <ContentOperation class="ContentBoxOpera">
            <span>未完全匹配菜品数量：<span style="color: rgba(0, 0, 0, 0.85);margin: 0 8px;">{{ SkuCount }}</span>个<pb-icon
                name="refresh" size="14" class="m-l2" style="cursor: pointer;" @click="resetFn2"></pb-icon></span>
            <pb-button size="small" plain v-hasPerm="'center:dishCost:export'">导出</pb-button>
          </ContentOperation>
          <div class="table-box flex">
            <div class="left-tree-box">
              <pb-tree :style="{ maxHeight: treeH }" :treeData="treeData" :defaultProps="treeProps"
                @nodeClick="nodeClick"></pb-tree>
            </div>
            <div class="table-right">
              <pb-table :column="bomColumn" :tableData="dishbomData" :indexWidth="60" :bottomElement="['pb-page']"
                :loading="loading">
                <template #pic="{ row }">
                  <img class="Imgs" :src="row.pic ? row.pic : '/src/assets/images/404.png'" alt="">
                </template>
                <template #roi="{ row }">
                  <span>{{ row.roi == null ? '' : row.roi >= 0 ? (row.roi === 0 ? '0%' : row.roi + '%') : '' }}</span>
                </template>
                <template #pricingType="{ row }">
                  {{ gettextprityep(row.pricingType) }}
                </template>
                <template #costStatus="{ row }">
                  <div class="flex boxcostStatus"><span class="costStatusradius"
                      :style="{ 'backgroundColor': row.costStatus == 1 ? '#09B562' : '' }"></span><span>{{
                        row.costStatus ==
                          1
                          ? '已确认'
                          : '未确认' }}</span></div>
                </template>
                <template #operate="{ row }">
                  <pb-button size="small" text @click="editBomfn(row)" v-hasPerm="'center:dishCost:edit'">编辑</pb-button>
                </template>
              </pb-table>
              <pb-pagination v-model:currentPage="pageObj.currentPage" v-model:pageSize="pageObj.pageSize"
                @onChange="currentChange" :total="pageObj.total"></pb-pagination>
            </div>
          </div>
        </div>
      </pb-card>
    </div>
    <pb-drawer v-model="isVisible" :title="'成本核算'" :direction="'btt'" :size="'92%'" @cancelFn="CancelFn"
      @confirmFn="confirmFn" v-if="isVisible">
      <div class="accountingFlge">
        <div class="flex chartbigbox">
          <div ref="chartContainer" style="width: 120px; height: 120px;">
          </div>
          <div class="chartcenter">
            <div>{{ Bomdata.totalCost ? Bomdata.totalCost.toFixed(2) : '0.00'
              }}元</div>
            <div>合计</div>
          </div>
          <div class="center">
            <div class="flex">
              <div style="min-width: 260px;">
                <span class="radius1"></span><span>食材成本：</span><span class="span1">{{ Bomdata.materialCost
                  }}</span><span>元</span>
              </div>
              <div>
                <span class="radius1" style="background: #2bd4bd;"></span><span>调料成本：</span><span class="span1">{{
                  Bomdata.seasoningCost
                }}</span><span>元</span>
              </div>
            </div>
            <div class="flex">
              <div style="min-width: 260px;">
                <span class="radius2"></span><span>耗材成本：</span><span class="span1">{{ Bomdata.conosumablesCost
                  }}</span><span>元</span>
              </div>
              <div>
                <span class="radius2" style="background: #ff576a;"></span><span>损耗成本：</span><span class="span1">{{
                  Bomdata.lossCost
                }}</span><span>元</span>
              </div>
            </div>
            <div class="flex items-center"><span class="radius3"></span><span>合计成本：</span><span class="span1">{{
              Bomdata.totalCost
                }}</span><span>元</span></div>
          </div>
        </div>
      </div>
      <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
        <el-tab-pane label="菜品BOM" name="first">
          <Bominfo :Bomdata="Bomdata" ref="refbominfo" />
        </el-tab-pane>
        <el-tab-pane label="耗材BOM" name="second">
          <Consuminfo :Bomdata="Bomdata" ref="refconsuminfo">
          </Consuminfo>
        </el-tab-pane>
      </el-tabs>
    </pb-drawer>
  </div>
</template>

<script lang="ts" setup>
import { createMessage } from "@/Public-UIlibrary/pb-message/method";
import Bominfo from './components/bominfo.vue'
import Consuminfo from './components/consuminfo.vue'
import { GetDishAccountingListApi, getDishTypeApi, GttDishBomDetalApi, EditSaveBatchApi, GetSkuDishCountApi, ReloadCostApi, GetDishTypeValueListApi } from '@/api/Dashmana'
import * as echarts from 'echarts';

const resetFn2 = async () => {
  loading.value = true
  await ReloadCostApi({})
  getDataFn()
}
const loading = ref(false)
// 创建一个响应式引用来存储图表实例和百分比值
const chartContainer = ref(null);
const chartInstance = ref(null);
const percentage = ref(25); // 初始百分比值
const refconsuminfo = ref()
const refbominfo = ref()
const gettextprityep = (text: string) => {
  if (text == 'portion') {
    return '计份'
  } else if (text == 'weight') {
    return '计重'
  } else {
    return '投产比'
  }
}
const priListOrigin = () => [
  { label: "全部", val: '', checked: true },
  { label: "计份", val: 'portion', checked: false },
  { label: "计重", val: 'weight', checked: false },
  { label: "投产比", val: 'roi', checked: false },
];
const pristatusListOrigin = () => [
  { label: "全部", val: '', checked: true },
  { label: "已确认", val: 1, checked: false },
  { label: "未确认", val: 0, checked: false },
];
const primatchListOrigin = () => [
  { label: "全部", val: '', checked: true },
  { label: "未匹配", val: 0, checked: false },
  { label: "已匹配", val: 1, checked: false },
  { label: "其他", val: 2, checked: false }]
const statusList = ref(pristatusListOrigin())
const priList = ref(priListOrigin())
const matchList = ref(primatchListOrigin())
// 更新图表数据（如果需要动态改变进度）
const updateProgress = (newValue) => {
  if (chartInstance.value) {
    chartInstance.value.setOption({
      series: [{
        data: [{ value: newValue, name: '完成度' }]
      }]
    });
    percentage.value = newValue; // 更新显示的百分比值
  }
};
const handleClick = () => {

}
const Bomdata = ref({} as any)
const activeName = ('first')
const treeData = ref([] as any)
const treeProps = { children: "children", label: "dishTypeName" };
const isVisible = ref(false)
const clearObjKey = (clearForm: any) => {
  Object.keys(clearForm).forEach((key: any) => {
    if (Array.isArray(clearForm[key])) {
      // 如果属性是数组，则清空数组
      clearForm[key].length = 0;
    } else {
      // 如果属性不是数组，则设置为默认值（默认为空字符串）
      clearForm[key] = '';
    }
  });
}
const SetpricingFn = (el: any) => {
  dishbomForm.pricingType = el.val
  getDataFn()
}
const SetcostStatusFn = (el: any) => {
  dishbomForm.costStatus = el.val
  getDataFn()
}
const SetskuStatusFn = (el: any) => {
  dishbomForm.skuStatus = el.val
  getDataFn()
}
const nodeClick = (data: any) => {
  dishbomForm.dishTypeCode = data.curNode.dishTypeCode
  getDataFn()
};
const editBomfn = (row: any) => {
  // Bomdata.value.dishId = row.dishId
  Object.assign(Bomdata.value, row)
  isVisible.value = true
  nextTick(() => {
    initecharts(row)
  })
}
const CancelFn = () => {
  Object.assign(Bomdata.value, {})
  getSkuCountFn()
  isVisible.value = false
}
const confirmFn = () => {
  // Object.assign(Bomdata.value, {})
  getSkuCountFn()
  EditSaveBatchApi({
    "dishId": Bomdata.value.dishId,
    "dishBomList": refbominfo.value.getdishbominfoDatafn(),
    "dishConsumablesList": refconsuminfo.value.getconsuinfoDatafn()
  }).then(res => {
    if (res.code == 2000) {
      createMessage({
        message: '编辑成功'
      })
      Object.assign(Bomdata.value, {})
      getDataFn()
      isVisible.value = false
    }
  })
}
let treeH = ref(null)
const getNodeDishType = () => {
  treeData.value.length = 0
  getDishTypeApi({
    type: 'weight'
  }).then(res => {
    treeData.value.push({
      dishTypeCode: '',
      dishTypeName: '全部',
      children: res.data
    })
    getDataFn()

    var height = document.getElementsByClassName("pb-table");
    treeH.value = height[0].offsetHeight + "px";

    window.addEventListener("resize", () => {
      height = document.getElementsByClassName("pb-table");

      treeH.value = height[0].offsetHeight + "px";
    });
  })
}
const dishbomForm = reactive({
  dishCode: '',
  dishName: '',
  spuName: '',
  pricingType: '',
  dishTypeCode: '',
  auditStatus: 1,
  skuStatus: '',
  costStatus: null,
  useScopeAttributeId: null
})
const pageObj = reactive({
  total: 0,
  currentPage: 1,
  pageSize: 10,
})

const currentChange = () => {
  getDataFn()
}
const bomColumn = reactive([
  {
    slot: "pic",
    name: "图片",
    width: 60
  },
  {
    key: "dishCode",
    name: "菜品编码",
    align: "right",
  },
  {
    key: "dishName",
    name: "菜品名称",
  },
  {
    key: "dishTypeName",
    name: "菜品分类",
    width: 100
  },
  {
    key: 'dishUseScopeName',
    name: '供餐模式',
    width: 100
  }, {
    key: "materialCost",
    name: "原料成本",
    align: "right",
  }, {
    key: "conosumablesCost",
    name: "耗材成本",
    align: "right",
  },
  {
    key: "seasoningCost",
    name: "调料成本",
    align: "right",
  },
  {
    key: 'lossCost',
    name: "损耗成本",
    align: "right",
  }, {
    key: "totalCost",
    name: "合计成本(元)",
    align: "right",
    width: 120
  },
  {
    slot: "costStatus",
    name: "成本状态",
  },
  {
    slot: 'roi',
    name: '投产比(%)',
    align: "right",
  }, {
    slot: "pricingType",
    name: "定价方式",
  },
  {
    slot: "operate",
    name: "操作",
    width: 70
  },
]);
const dishbomData = ref([] as any)
const searchFn = () => {
  getDataFn()
}
const resetFn = () => {
  clearObjKey(dishbomForm)
  priList.value.map(el => {
    el.checked = false
  })
  scopepriList.value.map(el => {
    el.checked = false
  })
  statusList.value.map(el => {
    el.checked = false
  })
  matchList.value.map(el => {
    el.checked = false
  })
  statusList.value[0].checked = true
  priList.value[0].checked = true
  matchList.value[0].checked = true
  scopepriList.value[0].checked = true
  getDataFn()
}
const getDataFn = () => {
  loading.value = true
  dishbomData.value.length = 0
  GetDishAccountingListApi({
    "currentPage": pageObj.currentPage,
    "pageSize": pageObj.pageSize,
    "sortingFields": [
      {
        "field": "",
        "order": ""
      }
    ],
    "dishCode": dishbomForm.dishCode,
    "dishName": dishbomForm.dishName,
    "pricingType": dishbomForm.pricingType,
    "dishTypeCode": dishbomForm.dishTypeCode,
    "costStatus": dishbomForm.costStatus,
    "skuStatus": dishbomForm.skuStatus,
    "useScopeAttributeId": dishbomForm.useScopeAttributeId
  }).then((res: any) => {
    loading.value = false
    dishbomData.value = res.data.records
    pageObj.total = res.data.total
  }).catch(err => {
    loading.value = false
  }).finally(errs => {
    loading.value = false
  })
}
const initecharts = (row) => {
  // console.log(chartContainer.value, '1')
  if (chartContainer.value) {
    // console.log(chartContainer.value, '2')
    chartInstance.value = echarts.init(chartContainer.value);
    const option = {
      tooltip: {
        trigger: 'none'
      },
      legend: {
        top: '5%',
        left: '20'
      },
      color: ['#2563EB', '#F97316', '#2bd4bd', '#ff576a'
      ],
      series: [
        {
          type: 'pie',
          radius: ['55%', '70%'],
          avoidLabelOverlap: false,
          padAngle: 5,
          itemStyle: {
          },
          label: {
            show: false,
            position: 'center'
          },
          emphasis: {
            label: {
              show: true,
              fontSize: 40,
              fontWeight: 'bold'
            }
          },
          labelLine: {
            show: false
          },
          data: [
            { value: row.materialCost, },
            { value: row.conosumablesCost, },
            { value: row.seasoningCost },
            { value: row.lossCost }
          ]
        }
      ]
    };
    chartInstance.value.setOption(option);
  }
}
const SkuCount = ref(null as any)
const getSkuCountFn = () => {
  GetSkuDishCountApi({}).then(res => {
    // console.log(res)
    SkuCount.value = res.data.dishPricingNoMatchSkuCount
  })
}
const scopepriList = ref([{
  label: '全部',
  val: null,
  checked: true
}] as any)

const SetscopepricingFn = (el: any) => {
  dishbomForm.useScopeAttributeId = el.val
  getDataFn()
}
onMounted(() => {
  getNodeDishType()
  getSkuCountFn()
  GetDishTypeValueListApi({
    "currentPage": 0,
    "pageSize": -1,
    "sortingFields": [
      {
        "field": "",
        "order": ""
      }
    ],
    "dishAttributeType": ""
  }).then((res) => {
    res.data.records.forEach((el: any) => {

      if (el.dishAttributeType == 'scope') {
        scopepriList.value.push({
          label: el.dishAttributeValue,
          val: el.dishAttributeValueId,
          checked: false
        })
      }
      scopepriList.value[0].checked = true
    })
  })
})
// 清理图表实例（在组件卸载时）
onUnmounted(() => {
  if (chartInstance.value) {
    chartInstance.value.dispose();
  }
});
</script>

<style lang="scss" scoped>
// ::v-deep thead th {
//   background: #F5F5F5 !important;
//   padding: 9px 5px !important;
//   font-weight: 400;
//   font-size: 14px;
//   color: rgba(0, 0, 0, 0.65);
// }

.dishaccounting {
  .left-tree-box {
    width: 15.6%;
  }

  .table-right {
    flex: 1;
    padding: 16px;
    box-sizing: border-box;

    .ceshi {
      position: absolute;
      top: 0;
      left: 0;
    }
  }

  .boxcostStatus {
    align-items: center;

    .costStatusradius {
      width: 6px;
      height: 6px;
      background: #F52F3E;
      display: inline-block;
      border-radius: 50%;
      margin-right: 4px;
    }
  }

  .accountingFlge {
    width: 100%;

    .center {
      margin-top: 20px;
      margin-left: 20px;
      font-family: PingFang SC, PingFang SC;
      font-weight: 400;
      font-size: 16px;
      color: rgba(0, 0, 0, 0.65);

      >div {
        margin-bottom: 6px;
      }

      .span1 {
        font-family: PingFang SC, PingFang SC;
        font-weight: 600;
        font-size: 16px;
        color: rgba(0, 0, 0, 0.85);
      }

      span {
        margin-right: 6px;
      }
    }

    .radius1,
    .radius2,
    .radius3 {
      width: 8px;
      height: 8px;
      border-radius: 1px 1px 1px 1px;
      display: inline-block;
      margin-right: 16px;
    }

    .radius1 {
      background: #2563EB;
    }

    .radius2 {
      background: #F97316;
    }
  }

  .chartbigbox {
    position: relative;

    .chartcenter {
      position: absolute;
      left: 11px;
      top: 44px;
      text-align: center;
      width: 100px;
    }
  }

  .ContentBoxOpera {
    justify-content: space-between;
    align-items: center;
    font-family: PingFang SC, PingFang SC;
    font-weight: 400;
    font-size: 16px;
    color: rgba(0, 0, 0, 0.65);
  }

  .Imgs {
    width: 38px;
    height: 38px;
  }
}
</style>
